# [六] Bean的实例化-注解支持

注解支持

注解的实现过程,其实就是Spring Bean的自动装配过程,存在于Srping bean的生命周期中,Spirng 中有三种bean的装配机制:

  • 1、xml进行显示配置
  • 2、java中进行显示配置
  • 3、隐式的bean发现机制和自动装配 所以要想了解Spring中的注解原理,首先需要了解注解的装配过程。

# 注解处理的入口

Spring初始化过程中,调用注解处理的几个主要埋点

  • │ ├─ refresh
  • │ │ ├─ prepareRefresh
  • │ │ ├─ obtainFreshBeanFactory XML文件解析,component-scan属性解析
  • │ │ ├─ prepareBeanFactory
  • │ │ ├─ postProcessBeanFactory
  • │ │ ├─ invokeBeanFactoryPostProcessors
  • │ │ ├─ registerBeanPostProcessors 实例化注解处理器
  • │ │ ├─ initMessageSource
  • │ │ ├─ initApplicationEventMulticaster
  • │ │ ├─ registerListeners
  • │ │ ├─ finishBeanFactoryInitialization
  • │ │ ├─ getObjectForBeanInstance
  • │ │ ├─ getBean
  • │ │ │ ├─ createBean
  • │ │ │ │ ├─ doCreateBean
  • │ │ │ │ │ ├─ createBeanInstance
  • │ │ │ │ │ │ ├─ determineConstructorsFromBeanPostProcessors 解析构造函数是否有@Autowired
  • │ │ │ │ │ ├─ applyMergedBeanDefinitionPostProcessors 注解的搜集和装配过程
  • │ │ │ │ │ ├─ earlySingletonExposure
  • │ │ │ │ │ ├─ addSingletonFactory
  • │ │ │ │ │ ├─ populateBean
  • │ │ │ │ │ │ ├─ postProcessProperties 根据收集到的注解进行反射调用
  • │ │ │ │ │ │ │ ├─ AutowiredFieldElement.inject 解析有@Autowired注解域的注入
  • │ │ │ │ │ │ │ ├─ AutowiredMethodElement.inject 解析有@Autowired注解方法的注入
  • │ │ │ │ │ ├─ initializeBean
  • │ │ │ │ │ │ ├─ applyBeanPostProcessorsBeforeInitialization 解析处理@PostConstruct
  • │ │ │ │ │ │ ├─ invokeInitMethods
  • │ │ │ │ │ │ ├─ applyBeanPostProcessorsAfterInitialization AOP的入口
  • │ │ │ ├─ afterSingletonCreation
  • │ │ │ └─ addSingleton

# 注解的装配与收集

装配过程

  • 1、根据xml文件<context:component-scan>标签中的类路径或者@ComponentScan注解中的类路径进行扫描解析,将包含@Component和元注解为@Component的注解@Controller、@Service、@Repository还有支持Java EE 6的@link javax.annotation.ManagedBeanJSR-330的 @link javax.inject.Named的bean封装到BeanDefinition对象后,最后注册到BeanFactory中。

  • 2、注册注解后置处理器,主要由BeanPostProcessor来负责解析,具体包括:

    • ConfigurationClassPostProcessor: 注册@Configuration处理器。
    • AutowiredAnnotationBeanPostProcessor:注册@Autowired、@Value、@Inject(JSR-330)处理器。
    • RequiredAnnotationBeanPostProcessor:注册@Required处理器。
    • PersistenceAnnotationBeanPostProcessor:支持Jpa的条件下,处理Jpa相关注解 。
    • EventListenerMethodProcessor:注册@EventListener处理器。
    • InitDestroyAnnotationBeanPostProcessor:处理@PostConstruct、@PreDestroy 注解的解析。
    • CommonAnnotationBeanPostProcessor:在支持JSR-250条件下注册JDK中javax.annotation包中注解处理器(@PostConstruct、@PreDestroy、@Resource、@Resources、@Generated)。

注解后置处理器的收集过程

@Autowired@Resource注解的收集过程基本一致,流程如下:

  • 1、看缓存里面有没有 InjectionMetadata对象
  • 2、从类中获取所有 Field 对象,循环 Field 对象,判断 Field 有没有@Resource注解, 如果有注解封装成 ResourceElement对象
  • 3、从类中获取所有 Method对象,循环 Method对象,判断 Method有没有@Resource 注解,如果有注解封装成 ResourceElement对象
  • 4、然后把两个 Field 和 Method封装的对象集合封装到 InjectionMetadata对象中
  • 5、最终把返回的 InjectionMetadata 对象存到ConcurrentHashMap 缓存中。

# 常用注解的处理器

# CommonAnnotationBeanPostProcessor

概述

CommonAnnotationBeanPostProcessor支持了@PostConstruct、@PreDestroy、@Resource等注解的解析工作,但是真正对@PostConstruct、@PreDestroy两个注解的解析是由其父类InitDestroyAnnotationBeanPostProcessor来完成的。

源码

	// CommonAnnotationBeanPostProcessor的构造函数,支持了@PostConstruct、@PreDestroy
	public CommonAnnotationBeanPostProcessor() {
		setOrder(Ordered.LOWEST_PRECEDENCE - 3);
		setInitAnnotationType(PostConstruct.class);
		setDestroyAnnotationType(PreDestroy.class);
		ignoreResourceType("javax.xml.ws.WebServiceContext");
	}
	
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		//扫描@PostConstruct @PreDestroy
		super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
		//扫描@Resource,扫描属性和方法上面是否有@Resource注解,如果有则收集起来封装成对象
		InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}

# AutowiredAnnotationBeanPostProcessor

概述

AutowiredAnnotationBeanPostProcessor后置处理器,主要处理@Autowired的解析。

类图

  • PriorityOrdered:确认 AutowiredAnnotationBeanPostProcessor 后置处理器的执行优先级
  • BeanFactoryAware:使得AutowiredAnnotationBeanPostProcessor 可以直接通过BeanFactory获取容器中的Bean
  • BeanPostProcessor:在 Bean 初始化前后执行的后置处理器
  • InstantiationAwareBeanPostProcessor:在 Bean 实例化前后和Bean设置属性值时执行的后置处理器
  • SmartInstantiationAwareBeanPostProcessor:智能实例化Bean的后处理器,如预测Bean的类型和确认Bean的构造函数等。
  • MergedBeanDefinitionPostProcessor:合并Bean的定义信息。

Spring 注解的装配收集源码

/**
 *  TODO : 注解装配过程的核心方法,
 *  BeanPostProcessor接口的典型运用,这里要理解这个接口
 */
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof MergedBeanDefinitionPostProcessor) {
				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
			}
		}
	}